package bb.lanxing.device.sgdevcie.home

import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.Gravity
import android.view.View
import androidx.activity.result.ActivityResultRegistry
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import bb.lanxing.R
import bb.lanxing.activity.base.WebActivity
import bb.lanxing.databinding.DataBindingAdapters
import bb.lanxing.databinding.FragmentXossDeviceHomeSgActivityBinding
import bb.lanxing.device.sgdevcie.setting.XossDeviceSGSettingEntryActivity
import bb.lanxing.device.sgdevcie.tool.BluetoothPermissionDialog
import bb.lanxing.device.sgdevcie.tool.XossDeviceConstants.DeviceUIState
import bb.lanxing.device.sgdevcie.viewmodel.DeviceViewModel
import bb.lanxing.device.sgdevcie.xpair.XPairLauncher
import bb.lanxing.device.sync.XossDeviceAutoSyncManager
import bb.lanxing.lib.devices.api.SmartDevice
import bb.lanxing.lib.devices.base.DeviceContext
import bb.lanxing.manager.SharedManager
import bb.lanxing.model.database.DeviceInfo
import bb.lanxing.mvvm.base.BaseDBFragment
import bb.lanxing.mvvm.base.IPermissionInspector
import bb.lanxing.mvvm.base.viewmodel.ContextAction.ACTION_FINISH
import bb.lanxing.mvvm.base.viewmodel.ContextAction.ACTION_HIDE_LOADING
import bb.lanxing.mvvm.base.viewmodel.ContextAction.ACTION_REFRESH
import bb.lanxing.mvvm.base.viewmodel.ContextAction.ACTION_SHOW_LOADING
import bb.lanxing.mvvm.base.viewmodel.TipAction
import bb.lanxing.util.RxPermissionUtil
import bb.lanxing.util.SensorEnableUtil
import bb.lanxing.util.ui.ChoiceBottomSheetFragment.ChoiceBottomSheetFragmentActionHandler
import bb.lanxing.util.ui.RemoveDeviceBottomSheetDialog
import bb.lanxing.view.PopupMenu
import bb.lanxing.view.sport.DragStopView.STATE_END
import bb.lanxing.view.sport.DragStopView.StateChangedCallback
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.launch
import java.util.concurrent.TimeUnit

class XossDeviceHomeSGFragment :
    BaseDBFragment<FragmentXossDeviceHomeSgActivityBinding>(R.layout.fragment_xoss_device_home_sg_activity) {
    var deviceAddress = ""
    var deviceName = ""
    var deviceType: Int = SmartDevice.TYPE_XOSS_NAV
    private val startSettingActivityLauncher = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { result ->
        result.data?.let {
            if (it.getBooleanExtra("RESET_DEVICE_FLAG", false)) {
                deviceViewModel.removeDevice(false)
                onBackPressed()
            }
        }

    }
    private val startStorageActivityLauncher = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { _ ->

    }
    var xPairLauncher: XPairLauncher? = null
    private val deviceViewModel by viewModels<DeviceViewModel>()
    override fun onCreate(bundle: Bundle?) {
        super.onCreate(bundle)
        Log.d("wangsm_bt"," wangsm,XossDeviceHomeSGFragment onCreate: ")
        val activityResultRegistry: ActivityResultRegistry? = activity?.activityResultRegistry
        xPairLauncher = XPairLauncher(activity, activityResultRegistry)
        lifecycle.addObserver(xPairLauncher!!)
        val arguments = arguments
        if (arguments != null) {
            val string = arguments.getString("EXTRA_DEVICE_ADDRESS", null)
            this.deviceAddress = string
            val string2 = arguments.getString("EXTRA_DEVICE_NAME", null)
            this.deviceName = string2
            this.deviceType = arguments.getInt("EXTRA_DEVICE_TYPE", 17)
            deviceViewModel.init(this.deviceAddress, this.deviceName, this.deviceType)
            Log.d("wangsm_bt", " activity XossDeviceHomeSGFragment,oncreate get device name: $deviceName")
        }
    }

    private fun initEvent() {
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                deviceViewModel.progressStateFlow.collect {
                    updateProgress(it)
                }
            }
        }
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                deviceViewModel.workoutSyncIndexStateFlow.collect {
                    binding.deviceActionTvIndicatorWorkout.text =
                        getString(R.string.st_workout_indicator, it.first, it.second)
                }
            }
        }
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                deviceViewModel.deviceUIStateStateFlow.debounce(300L).collect {
                    refreshCurrentDeviceState(it)
                }
            }
        }
        deviceViewModel.readDisStateLiveData.observe(this) {
            lifecycleScope.launch(Dispatchers.Main) {
                binding.tvDeviceFirmWareVersion.text = deviceViewModel.firmwareVersion
            }
        }
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                deviceViewModel.getGnssExpiredTime().collect {
                    refreshGNSSExpiredTime(it)
                }
            }
        }

        deviceViewModel.firmwareDetailEntityFlow.observe(this) {
            refreshFirmwareInfo()
        }
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                deviceViewModel.memoryUsageFlow.collect {
                    refreshStorageMessage(it)
                }
            }
        }
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                deviceViewModel.removeDeviceStateLiveEvent.observe(this@XossDeviceHomeSGFragment) {
                    if (it) {
                        DeviceContext.startAndRefreshAutoConnector()
                        toast(R.string.st_remove_success)
                        getActivity()?.onBackPressed()
                    } else {
                        toast(R.string.st_remove_failed)
                    }
                }
            }
        }
        deviceViewModel.tipsMutableLiveData.observe(this) {
            Observer<TipAction> { tipAction ->
                snack(tipAction.msg, tipAction.isSuccess)
            }
            deviceViewModel.actionLiveData.observe(this) { contextAction ->
                when (contextAction.action) {
                    ACTION_FINISH -> {}
                    ACTION_SHOW_LOADING -> {}
                    ACTION_HIDE_LOADING -> {}
                    ACTION_REFRESH -> {}
                }
            }
        }
    }

    private fun initViewEvent() {
        binding.tvDevices.setOnClickListener {
            requireActivity().onBackPressed()
        }
        binding.imgOption.setOnClickListener {
            PopupMenu(requireContext(), it, Gravity.TOP).apply {
                inflate(R.menu.menu_device_home_sg)
                setOnMenuItemClickListener { menu ->
                    when (menu.itemId) {
                        R.id.menu_import_log -> {
                            val intent = Intent(getActivity(), ReportDeviceLogActivity::class.java)
                            intent.putExtra("EXTRA_DEVICE_ADDRESS", deviceAddress)
                            intent.putExtra("EXTRA_DEVICE_TYPE", deviceType)
                            intent.putExtra("EXTRA_DEVICE_NAME", deviceName)
                            startActivity(intent)
                        }

                        R.id.menu_item_add_new -> {
                            xPairLauncher?.launchForNav()
                        }

                        R.id.menu_item_auto_sync -> {
                            deviceViewModel.autoInitDevice(true)
                        }

                        R.id.menu_item_remove -> {
                            RemoveDeviceBottomSheetDialog.show(parentFragmentManager,
                                object : ChoiceBottomSheetFragmentActionHandler {
                                    override fun onNegativeBtnClick(bottomSheetDialogFragment: BottomSheetDialogFragment?) {
                                        bottomSheetDialogFragment?.dismiss()
                                    }

                                    override fun onPositiveBtnClick(bottomSheetDialogFragment: BottomSheetDialogFragment?) {
                                        bottomSheetDialogFragment?.dismiss()
                                        deviceViewModel.removeDevice(false)
                                    }
                                })
                        }

                    }
                    true
                }
            }.show()
        }
    }

    override fun initView(binding: FragmentXossDeviceHomeSgActivityBinding) {
        initEvent()
        initViewEvent()
        val deviceInfoToAddress = DeviceInfo.getDeviceInfoToAddress(this.deviceAddress)
        DataBindingAdapters.setDeviceIcon(binding.imgDevice, deviceType, deviceInfoToAddress?.model)
        val str = deviceInfoToAddress?.firmwareVersion ?: ""
        binding.tvDeviceFirmWareVersion.text = str
        binding.controlDragStopView.stateChangedCallback = StateChangedCallback { i ->
            if (i == STATE_END) {
                showLoadingDialog(R.string.loading, true)
                deviceViewModel.requestDeviceRecordState(2) {
                    binding.controlDragStopView.setState(0, true)
                    dismissLoadingDialog()
                }
            }
        }
        binding.swipeRefresh.setOnRefreshListener {
            refreshLastTransTime()
            deviceViewModel.getDeviceStatus {
                binding.swipeRefresh.isRefreshing = false
            }
        }
        binding.switchAutoSync.isChecked =
            SharedManager.getInstance().isThisDeviceAutoSync(this.deviceAddress, true)
        binding.switchAutoSync.setOnCheckedChangeListener { _, z ->
            SharedManager.getInstance().setThisDeviceAutoSync(deviceAddress, z)
            Log.d("wangsm_bt"," switchAutoSync,status: $z" )
            if (z) {///wangsm sync method

                deviceViewModel.autoInitDevice(true)
            }
            XossDeviceAutoSyncManager
        }
        binding.tvReConnect.setOnClickListener {
            checkBluetoothPermission {
                refreshDevice()
            }
        }
        binding.tvUpdate.setOnClickListener {
            onGoDfuFirmware()
        }
        binding.llStorage.setOnClickListener {
        }
        binding.llPanel.setOnClickListener {
            onGoDataLayer()
        }

        binding.llSetting.setOnClickListener {
            onGoSettings()
        }

        binding.imgSync.setOnClickListener {
            syncGNSSDataManually()
        }
        binding.llFirewareUpdate.setOnClickListener {

        }
        binding.llManualBook.setOnClickListener {
            onGoManualBook()
        }
        binding.llHelp.setOnClickListener {
            onGoSupport()
        }
        request()

    }

    private fun onGoSettings() {
        val intent = Intent(requireActivity(), XossDeviceSGSettingEntryActivity::class.java).apply {
            putExtra("EXTRA_DEVICE_ADDRESS", deviceAddress)
            putExtra("EXTRA_DEVICE_TYPE", deviceType)
            putExtra("EXTRA_DEVICE_NAME", deviceName)
        }
        startSettingActivityLauncher.launch(intent)
    }

    private fun onGoDataLayer() {
//        DataLayoutBridgeActivity.Companion.launch(
//            requireContext(),
//            xossSGDeviceViewModel.deviceModel,
//            deviceAddress,
//            deviceName
//        )
    }

    private fun onGoManualBook() {
        val intent = Intent(requireActivity(), WebActivity::class.java)
//        if (xossSGDeviceViewModel.deviceModel == XossModelUtil.XossNAVSerial.A2.getModel()) {
//            intent.putExtra("web_url", "https://" + BiciHttpClient.DOMAIN_BASE + "/document/558");
//        } else {
//            intent.putExtra(
//                "web_url",
//                ("https://" + BiciHttpClient.DOMAIN_BASE) + "/document/521"
//            )
//        }
    }

    private fun onGoSupport() {
        val intent = Intent(requireActivity(), WebActivity::class.java)
//        if (xossSGDeviceViewModel.deviceModel == XossModelUtil.XossNAVSerial.A2.getModel()) {
//            intent.putExtra("web_url", "https://support.xoss.co/hc/xing/zh_Hans_CN")
//        } else {
//            intent.putExtra(
//                "web_url",
//                ("https://" + BiciHttpClient.DOMAIN_BASE) + "/document/522"
//            )
//        }
        startActivity(intent)
    }

    private fun onGoDfuFirmware() {
        deviceViewModel.dfuDeviceFound?.let {
//            val companion: UpdateDeviceIntroActivity.Companion = UpdateDeviceIntroActivity.Companion
//            companion.start(requireContext(), it.first, it.second)
        }
    }

    private fun syncGNSSDataManually() {
        if (deviceViewModel.deviceUIStateStateFlow.value == DeviceUIState.CONNECTED) {
            deviceViewModel.syncSatelliteGNSSDate(
                requireContext(), TimeUnit.MICROSECONDS.convert(18L, TimeUnit.SECONDS).toInt()
            ) {
                if (it) {
                    snack(R.string.gnss_file_is_up_to_date, true)
                } else {
                    snack(R.string.gnss_file_update_failed, true)
                }
            }
        }
    }

    private fun request() {
        refreshCurrentDeviceState(deviceViewModel.deviceUIStateStateFlow.value)
        refreshStorageMessage(deviceViewModel.memoryUsageFlow.value)
        refreshGNSSExpiredTime(deviceViewModel.getGnssExpiredTime().value)
        refreshFirmwareInfo()
        refreshDevice()
        refreshLastTransTime()
    }

    private fun refreshStorageMessage(pair: Pair<Long, Long>) {
        DataBindingAdapters.setStorageMemory(binding.tvStorage, pair.first, pair.second)
    }

    private fun refreshGNSSExpiredTime(j: Long) {
        if (j > 1) {
            val currentTimeMillis = (j * 1000) - System.currentTimeMillis()
            val j2 = if (currentTimeMillis < 0) 0L else currentTimeMillis / 86400000
            if (j2 <= 0) {
                val textView2 = binding?.tvSatelliteExpiresIn
                textView2?.apply {
                    text = getString(R.string.st_Expired)
                    setTextColor(
                        ResourcesCompat.getColor(
                            resources, R.color.common_red, null
                        )
                    )
                }
                return
            }
            val textView = binding?.tvSatelliteExpiresIn
            textView?.setTextColor(
                ResourcesCompat.getColor(
                    textView.resources, R.color.grey_999999, null
                )
            )
        }
    }

    private fun refreshCurrentDeviceState(deviceUIState: DeviceUIState) {
        DataBindingAdapters.getDeviceStateString(
            binding.deviceStateTv, deviceUIState, 0
        )
        if (deviceUIState == DeviceUIState.CONNECTED) {
            refreshLastTransTime()
        }
    }

    private fun refreshFirmwareInfo() {
        lifecycleScope.launch {
            try {
                deviceViewModel.firmwareDetailEntityFlow.value?.let {
                    if (it.need_update) {
                        binding.tvDeviceFirmWareVersion.visibility = View.GONE
                        binding.tvGoFirmwareUpdate.visibility = View.VISIBLE
                    } else {
                        binding.tvDeviceFirmWareVersion.visibility = View.VISIBLE
                        binding.tvGoFirmwareUpdate.visibility = View.GONE
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    private fun refreshLastTransTime() {
        if (deviceViewModel.lastTransmissionTime > 1) {
            val textView = binding.deviceActionSyncContent
            textView.text = getString(
                R.string.last_sync_content, DataBindingAdapters.getFriendlyTimeInterval(
                    requireContext(), deviceViewModel.lastTransmissionTime
                )
            )
        }
    }

    private fun refreshDevice() {
        lifecycleScope.launch {
            binding.tvTitle.text = deviceViewModel.deviceName
            deviceViewModel.refreshDeviceStateAndConnect(object :
                DeviceViewModel.ConnectCallBack {
                override fun onConnectResult(z: Boolean) {
                }

                override fun onDeviceAlreadyConnected() {
                    autoInitDevice()
                }

                override fun onServiceDiscovered() {
                }

            })
        }
    }

    fun autoInitDevice() {
        lifecycleScope.launch {
            if (deviceViewModel.isDeviceFreeAndNotInTransmission) {
                deviceViewModel.xossDeviceController?.let {
                    if (it.isInit) {
                        if (deviceViewModel.deviceUIStateStateFlow.value == DeviceUIState.CONNECTED) {
                            binding.swipeRefresh.post {
                                binding.swipeRefresh.isRefreshing = true
                            }
                            deviceViewModel.getDeviceStatus {
                                binding.swipeRefresh.post {
                                    binding.swipeRefresh.isRefreshing = false
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    fun resetProgress() {
        val progressBar = binding.deviceActionHorProgress
        progressBar.progress = 0
    }

    private fun updateProgress(f: Float) {
        val progressBar = binding.deviceActionHorProgress
        progressBar.progress = f.toInt()
    }

    fun setUpDeviceInfo(deviceType: Int, deviceAddress: String, deviceName: String) {
        this.deviceType = deviceType
        this.deviceAddress = deviceAddress
        this.deviceName = deviceName
    }

    private fun checkBluetoothPermission(grantedCallBack: () -> Unit) {
        val bluetoothPermissions = RxPermissionUtil.getBluetoothPermissions()
        if (checkAndRequestPermissionsWithRationale(
                bluetoothPermissions,
                object : IPermissionInspector.PermissionRationaleCallback {
                    override fun onUnShowRationale() {
                    }

                    override fun onRequestRationale(permissionRationaleConfirmCallback: IPermissionInspector.PermissionRationaleConfirmCallback) {
                        val bluetoothPermissionDialog = BluetoothPermissionDialog.INSTANCE
                        val parentFragmentManager = parentFragmentManager
                        bluetoothPermissionDialog.show(
                            parentFragmentManager,
                            object : ChoiceBottomSheetFragmentActionHandler {
                                override fun onNegativeBtnClick(bottomSheetDialogFragment: BottomSheetDialogFragment) {
                                }

                                override fun onPositiveBtnClick(bottomSheetDialogFragment: BottomSheetDialogFragment) {
                                    bottomSheetDialogFragment.dismiss()
                                    permissionRationaleConfirmCallback.onRequestRationaleConfirmed()
                                }
                            })
                    }
                })
        ) {
            if (SensorEnableUtil.isSdkVersionAboveS() || !SensorEnableUtil.isSdkVersionAboveM() || (SensorEnableUtil.checkGPSPermission(
                    activity
                ) && SensorEnableUtil.checkGpsEnabled(activity) && SensorEnableUtil.checkBluetoothEnable(
                    activity, 11
                ))
            ) {
                grantedCallBack.invoke()
            }
        }
    }

    companion object {
        fun newInstance(
            deviceType: Int, deviceAddress: String, deviceName: String
        ): XossDeviceHomeSGFragment {
            val xossDeviceHomeSGFragment = XossDeviceHomeSGFragment()
            xossDeviceHomeSGFragment.setUpDeviceInfo(deviceType, deviceAddress, deviceName)
            return xossDeviceHomeSGFragment
        }
    }
}
